package com.wss.common.widget;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;

/**
 * 自定义加载框View
 * Created by 吴天强 on 2016/12/15.
 */
public class LVCircularRing extends Component implements Component.EstimateSizeListener,
        Component.DrawTask {

    private float mWidth = 0f;
    private float mPadding = 0f;
    private float startAngle = 0f;
    private Paint mPaint;
    private int bgColor = Color.argb(100, 245, 245, 245);//加载框背景色
    private int barColor = Color.argb(100, 245, 245, 245);//加载框动画色

    public LVCircularRing(Context context) {
        this(context, null);
    }

    public LVCircularRing(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public LVCircularRing(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);

        bgColor = attrSet.getAttr("bgColor").isPresent() ?
                Color.getIntColor(attrSet.getAttr("bgColor").get().getStringValue()) : bgColor;
        barColor = attrSet.getAttr("barColor").isPresent() ?
                Color.getIntColor(attrSet.getAttr("barColor").get().getStringValue()) : barColor;

        initPaint();

        setEstimateSizeListener(this);
        addDrawTask(this);
    }

    @Override
    public boolean onEstimateSize(int widthEstimateConfig, int heightEstimateConfig) {

        int width = EstimateSpec.getSize(widthEstimateConfig);
        int height = EstimateSpec.getSize(heightEstimateConfig);

        int mode = EstimateSpec.getMode(widthEstimateConfig);

        if (width > height) {
            mWidth = height;
        } else {
            mWidth = width;
        }
        setEstimatedSize(EstimateSpec.getSizeWithMode((int) mWidth, mode),
                EstimateSpec.getSizeWithMode((int) mWidth, mode));
        return true;
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        mPaint.setColor(new Color(bgColor));
        canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 2 - mPadding, mPaint);
        mPaint.setColor(new Color(barColor));
        RectFloat rectF = new RectFloat(mPadding, mPadding, mWidth - mPadding, mWidth - mPadding);
        Arc arc = new Arc();
        arc.setArc(startAngle, 100, false);
        canvas.drawArc(rectF, arc, mPaint);
    }

    private void initPaint() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE_STYLE);
        mPaint.setStrokeWidth(4);
    }

    public void startAnim() {
        stopAnim();
        startViewAnim(0f, 1f, 1000);
    }

    public void stopAnim() {
        if (valueAnimator != null) {
            valueAnimator.setLoopedCount(1);
            valueAnimator.cancel();
            valueAnimator.end();
        }
    }

    AnimatorValue valueAnimator;

    private AnimatorValue startViewAnim(float startF, final float endF, long time) {
        valueAnimator = new AnimatorValue();

        valueAnimator.setDuration(time);
        valueAnimator.setCurveType(Animator.CurveType.LINEAR);
        valueAnimator.setLoopedCount(AnimatorValue.INFINITE);//无限循环

        valueAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                float value = getAnimatedValue(v, startF, endF);
                startAngle = 360 * value;
                invalidate();
            }
        });

        valueAnimator.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {

            }

            @Override
            public void onStop(Animator animator) {

            }

            @Override
            public void onCancel(Animator animator) {

            }

            @Override
            public void onEnd(Animator animator) {

            }

            @Override
            public void onPause(Animator animator) {

            }

            @Override
            public void onResume(Animator animator) {

            }
        });

        if (!valueAnimator.isRunning()) {
            valueAnimator.start();
        }

        return valueAnimator;
    }

    /**
     * get the animated value with fraction and values
     *
     * @param fraction 0~1
     * @param values float array
     * @return float animated value
     */
    public static float getAnimatedValue(float fraction, float... values){
        if(values == null || values.length == 0){
            return 0;
        }
        if(values.length == 1){
            return values[0] * fraction;
        }else{
            if(fraction == 1){
                return values[values.length-1];
            }
            float oneFraction = 1f / (values.length - 1);
            float offFraction = 0;
            for (int i = 0; i < values.length - 1; i++) {
                if (offFraction + oneFraction >= fraction) {
                    return values[i] + (fraction - offFraction) * (values.length - 1) * (values[i + 1] - values[i]);
                }
                offFraction += oneFraction;
            }
        }
        return 0;
    }
}
